/*
 * Copyright (C) 2004, Velocityme Partnership
 * NodeUtil.java
 *
 * Created on 28 August 2004, 09:10
 */

package com.velocityme.www.utility;

import com.velocityme.entity.Action;
import com.velocityme.entity.Anchor;
import com.velocityme.entity.ContactDetailTypes;
import com.velocityme.entity.Contactable;
import com.velocityme.entity.Department;
import com.velocityme.entity.Group;
import com.velocityme.entity.Issue;
import com.velocityme.entity.LicenceManagement;
import com.velocityme.entity.Node;
import com.velocityme.entity.Organisation;
import com.velocityme.entity.Person;
import com.velocityme.entity.Project;
import com.velocityme.entity.Role;
import com.velocityme.entity.Sprint;
import com.velocityme.entity.State;
import com.velocityme.entity.Status;
import com.velocityme.entity.SystemNode;
import com.velocityme.entity.SystemProperties;
import com.velocityme.entity.Activity;
import com.velocityme.entity.Task;
import com.velocityme.entity.TaskStateMachine;
import com.velocityme.entity.User;
import com.velocityme.enums.NotificationMechanism;
import com.velocityme.enums.Permission;
import com.velocityme.session.ContactableLocal;
import com.velocityme.session.GroupLocal;
import com.velocityme.session.KeyLocal;
import com.velocityme.session.PersonLocal;
import com.velocityme.session.RoleLocal;
import com.velocityme.session.StateLocal;
import com.velocityme.session.StatusLocal;
import com.velocityme.session.TaskStateMachineLocal;
import com.velocityme.session.TreeLocal;
import com.velocityme.session.UserLocal;
import com.velocityme.www.dto.ButtonValue;
import com.velocityme.www.dto.IntegerString;
import com.velocityme.www.dto.IdName;
import com.velocityme.www.dto.MenuDTO;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;

/**
 *
 * @author  Robert
 */
public class NodeUtil {
    
    private static NodeUtil m_cachedNodeUtil = null;
    private Hashtable m_nodeTabs;
    private IntegerString[] m_months;
    private IntegerString[] m_days;
    private IntegerString[] m_hours;
    private IntegerString[] m_minutes;
    private IntegerString[] m_durationDays;
    private IntegerString[] m_durationHours;
    private IntegerString[] m_percentageCompletes;
    private IntegerString[] m_priorityPairs;
    
    /** Creates a new instance of NodeUtil */
    private NodeUtil() {
        m_nodeTabs = new Hashtable();
        m_nodeTabs.put("Node", new String[]{"Node", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("RootNode", new String[]{"Node", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("Sprint", new String[]{"Sprint", "Links", "Change Log", "BurnDown", "Person Time", "Time Report", "Unplanned", "User Access", "Group Access"});
        m_nodeTabs.put("Department", new String[]{"Department", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("Organisation", new String[]{"Organisation", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("Person", new String[]{"Person", "Links", "Change Log", "Person Time", "User Access", "Group Access"});
        m_nodeTabs.put("Group", new String[]{"Group", "Links", "Change Log", "My Access", "User Access", "Group Access"});
        m_nodeTabs.put("Role", new String[]{"Role", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("State", new String[]{"State", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("Status", new String[]{"Status", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("Action", new String[]{"Action", "Links", "Change Log", "Time", "Gantt", "BurnDown", "User Access", "Group Access"});
        m_nodeTabs.put("Anchor", new String[]{"Anchor", "Links", "Change Log", "Gantt", "User Access", "Group Access"});
        m_nodeTabs.put("Issue", new String[]{"Issue", "Links", "Change Log", "Time", "Gantt", "BurnDown", "User Access", "Group Access"});
        m_nodeTabs.put("Project", new String[]{"Project", "Links", "Change Log", "Time", "Gantt", "BurnDown", "User Access", "Group Access"});
        m_nodeTabs.put("TaskStateMachine", new String[]{"TaskStateMachine", "Links", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("User", new String[]{"User", "Links", "Change Log", "Logins", "My Access", "User Access", "Group Access"});
        m_nodeTabs.put("SystemNode", new String[]{"SystemNode", "Change Log", "User Access", "Group Access"});
        m_nodeTabs.put("ContactDetailTypes", new String[]{"ContactDetailTypes", "User Access", "Group Access"});
        m_nodeTabs.put("SystemProperties", new String[]{"SystemProperties", "User Access", "Group Access"});
        m_nodeTabs.put("LicenceManagement", new String[]{"LicenceManagement", "User Access", "Group Access"});
        m_nodeTabs.put("LoginHistory", new String[]{"LoginHistory", "User Access", "Group Access"});
        m_nodeTabs.put("Directory", new String[]{"Directory", "User Access", "Group Access"});
        m_months = new IntegerString[12];
        m_months[0] = new IntegerString(new Integer(0), "Jan");
        m_months[1] = new IntegerString(new Integer(1), "Feb");
        m_months[2] = new IntegerString(new Integer(2), "Mar");
        m_months[3] = new IntegerString(new Integer(3), "Apr");
        m_months[4] = new IntegerString(new Integer(4), "May");
        m_months[5] = new IntegerString(new Integer(5), "Jun");
        m_months[6] = new IntegerString(new Integer(6), "Jul");
        m_months[7] = new IntegerString(new Integer(7), "Aug");
        m_months[8] = new IntegerString(new Integer(8), "Sep");
        m_months[9] = new IntegerString(new Integer(9), "Oct");
        m_months[10] = new IntegerString(new Integer(10), "Nov");
        m_months[11] = new IntegerString(new Integer(11), "Dec");
        m_days = new IntegerString[31];
        for (int i = 0; i < m_days.length; i++)
            m_days[i] = new IntegerString(new Integer(i+1), Integer.toString(i+1));
        m_hours = new IntegerString[24];
        for (int i = 0; i < m_hours.length; i++)
            m_hours[i] = new IntegerString(new Integer(i), Integer.toString(i));
        m_minutes = new IntegerString[12];
        for (int i = 0; i < m_minutes.length; i++)
            m_minutes[i] = new IntegerString(new Integer(i*5), Integer.toString(i*5));
        m_durationDays = new IntegerString[30];
        for (int i = 0; i < m_durationDays.length; i++)
            m_durationDays[i] = new IntegerString(new Integer(i), Integer.toString(i));
        m_durationHours = new IntegerString[8];
        for (int i = 0; i < m_durationHours.length; i++)
            m_durationHours[i] = new IntegerString(new Integer(i), Integer.toString(i));
        m_percentageCompletes = new IntegerString[21];
        for (int i = 0; i < m_percentageCompletes.length; i++) {
            Integer p = new Integer(i*5);
            m_percentageCompletes[i] = new IntegerString(p, p.toString());
        }
        m_priorityPairs = new IntegerString[11];
        for (int i = 0; i < m_priorityPairs.length; i++) {
            Integer p = new Integer(i*10);
            m_priorityPairs[i] = new IntegerString(p, p.toString());
        }
    }
    
    public static NodeUtil getInstance() {
        if (m_cachedNodeUtil == null)
            m_cachedNodeUtil = new NodeUtil();
        return m_cachedNodeUtil;
    }
    
    public String[] getNodeTabs(String nodeType) {
        return (String[])m_nodeTabs.get(nodeType);
    }
    
    public IntegerString[] getYears() {
        int year = Calendar.getInstance().get(Calendar.YEAR);
        int start = year - 4;
        int stop = year + 4;
        IntegerString[] years = new IntegerString[stop-start+1];
        for (int i = start; i <= stop; i++) {
            years[i-start] = new IntegerString(new Integer(i), Integer.toString(i));
        }
        return years;
    }
    
    public IntegerString[] getMonths() {
        return m_months;
    }
    
    public IntegerString[] getDays() {
        return m_days;
    }
    
    public IntegerString[] getHours() {
        return m_hours;
    }
    
    public IntegerString[] getMinutes() {
        return m_minutes;
    }
    
    public IntegerString[] getDurationDays() {
        return m_durationDays;
    }
    
    public IntegerString[] getDurationHours() {
        return m_durationHours;
    }

    public IntegerString[] getPercentageCompletes() {
        return m_percentageCompletes;
    }

    public IntegerString[] getPriorityPairs() {
        return m_priorityPairs;
    }
    
    public MenuDTO getMenu(KeyLocal key, Node node, Set<Permission> permissions, boolean isValidPasteNode, boolean isValidLinkNode, boolean isValidDependencyNode, boolean isValidDependantNode) {
        MenuDTO menuDTO = new MenuDTO();
        // create file menu
        List fileList = new ArrayList();
        fileList.add(new ButtonValue(true, true, "file-home", "Home"));
        fileList.add(new ButtonValue(true, true, "file-logout", "Logout"));
        menuDTO.addMenu("File", fileList);
        if (node != null) {
            // create edit menu
            List editList = new ArrayList();
            editList.add(new ButtonValue(!(node instanceof SystemNode), false, "edit-node-mark", "Mark Node"));
            editList.add(new ButtonValue(isValidPasteNode, false, "edit-node-move", "Move Marked Node"));
            editList.add(new ButtonValue(permissions.contains(Permission.NODE_DELETE), false, "edit-node-delete", "Delete Node"));
            editList.add(new ButtonValue(isValidLinkNode, false, "edit-node-link", "Link Marked Node"));
            editList.add(new ButtonValue(isValidDependencyNode, false, "edit-node-dependency", "Mark Dependency"));
            editList.add(new ButtonValue(isValidDependantNode, false, "edit-node-dependant", "Mark Dependant"));
            menuDTO.addMenu("Edit", editList);
            // create Create menu
            List createList = new ArrayList();
            createList.add(new ButtonValue(permissions.contains(Permission.NODE_CREATE), true, "create-node", "Node"));
            createList.add(new ButtonValue(permissions.contains(Permission.SPRINT_CREATE), true, "create-sprint", "Sprint"));
            createList.add(new ButtonValue(permissions.contains(Permission.PROJECT_CREATE), true, "create-project", "NewProject"));
            createList.add(new ButtonValue(permissions.contains(Permission.ANCHOR_CREATE), true, "create-anchor", "Anchor"));
            createList.add(new ButtonValue(permissions.contains(Permission.ACTION_CREATE), true, "create-action", "Action"));
            createList.add(new ButtonValue(permissions.contains(Permission.ISSUE_CREATE), true, "create-issue", "Issue"));
            createList.add(new ButtonValue(node.getName().equals("Setup Organisations") && permissions.contains(Permission.ORGANISATION_CREATE), true, "create-organisation", "Organisation"));
            createList.add(new ButtonValue(((node instanceof Organisation) || (node instanceof Department)) && permissions.contains(Permission.DEPARTMENT_CREATE), true, "create-department", "Department"));
            createList.add(new ButtonValue(((node instanceof Organisation) || (node instanceof Department)) && permissions.contains(Permission.PERSON_CREATE), true, "create-person", "Person"));
            createList.add(new ButtonValue(node.getName().equals("Setup Users") && permissions.contains(Permission.USER_CREATE), true, "create-user", "User"));
            createList.add(new ButtonValue(node.getName().equals("Setup Groups") && permissions.contains(Permission.GROUP_CREATE), true, "create-group", "Group"));
            createList.add(new ButtonValue(node.getName().equals("Setup Task Types") && permissions.contains(Permission.TASK_TYPE_CREATE), true, "create-task-type", "Task Type"));
            createList.add(new ButtonValue(node.getName().equals("Setup States") && permissions.contains(Permission.STATE_CREATE), true, "create-state", "State"));
            createList.add(new ButtonValue(node.getName().equals("Setup Statuses") && permissions.contains(Permission.STATUS_CREATE), true, "create-status", "Status"));
            createList.add(new ButtonValue(node.getName().equals("Setup Roles") && permissions.contains(Permission.ROLE_CREATE), true, "create-role", "Role"));
            createList.add(new ButtonValue(permissions.contains(Permission.USER_ACCESS_CREATE), true, "create-user-access", "User Access"));
            createList.add(new ButtonValue(permissions.contains(Permission.GROUP_ACCESS_CREATE), true, "create-group-access", "Group Access"));
            menuDTO.addMenu("Create", createList);
        }
        // create search menu
        List searchList = new ArrayList();
        searchList.add(new ButtonValue(true, false, "search-tasks-all-responsible", "All My Responsible Tasks"));
        searchList.add(new ButtonValue(true, false, "search-tasks-all-interested", "All My Interested Tasks"));
        if (node != null) {
            searchList.add(new ButtonValue(true, false, "search-tasks-my-responsible", "My Responsible Tasks"));
            searchList.add(new ButtonValue(true, false, "search-tasks-my-interested", "My Interested Tasks"));
            searchList.add(new ButtonValue(true, false, "search-tasks-others-responsible", "Others Responsible Tasks"));
            searchList.add(new ButtonValue(true, false, "search-tasks-new", "New Tasks"));
            searchList.add(new ButtonValue(true, false, "search-tasks-active", "Active Tasks"));
            searchList.add(new ButtonValue(true, false, "search-tasks-completed", "Completed Tasks"));
            searchList.add(new ButtonValue(true, false, "search-tasks-changed", "Changed Tasks"));
            searchList.add(new ButtonValue(true, false, "search-tasks-advanced", "Advanced Search"));
            searchList.add(new ButtonValue(true, false, "search-time", "Time Report"));
        }
        menuDTO.addMenu("Search", searchList);
        // create Bookmark menu
        List bookmarkList = new ArrayList();
        if (node != null) {
            bookmarkList.add(new ButtonValue(true, false, "bookmark-add-node", "Add Bookmark"));
            bookmarkList.add(new ButtonValue(true, false, "bookmark-remove-node", "Remove Bookmark"));
        }
        if (key.getShowBookmarks() == false)
            bookmarkList.add(new ButtonValue(true, false, "bookmark-show", "Show Bookmarks"));
        else
            bookmarkList.add(new ButtonValue(true, false, "bookmark-hide", "Hide Bookmarks"));
        bookmarkList.add(new ButtonValue(false, false, "", ""));
        for (Node bookmarkNode: lookupTreeBean().getBookmarkNodes(key)) {
            bookmarkList.add(new ButtonValue(true, false, "bookmark-nodeId-" + bookmarkNode.getId(), bookmarkNode.getName()));
        }
        menuDTO.addMenu("Bookmarks", bookmarkList);
        // create Help menu
        List<ButtonValue> helpList = new ArrayList<ButtonValue>();
        helpList.add(new ButtonValue(true, false, "help-content", "Help Content"));
        helpList.add(new ButtonValue(true, false, "help-about", "Help About"));
        menuDTO.addMenu("Help", helpList);
        return menuDTO;
    }
    
    public List getNodeButtons(Node node, String tab, Set permissionPKs) {
        List buttonList = new ArrayList();
        if (node instanceof Contactable) {
            if (node instanceof Department) {
                if (tab.equals("Department")) {
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.DEPARTMENT_EDIT), true, "EditDepartment", "Edit"));
                }
            }
            if (node instanceof Organisation) {
                if (tab.equals("Organisation")) {
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.ORGANISATION_EDIT), true, "EditOrganisation", "Edit"));
                }
            }
            if (node instanceof Person) {
                if (tab.equals("Person")) {
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.PERSON_EDIT), true, "EditPerson", "Edit"));
                }
            }
        }
        if (node instanceof Group) {
            if (tab.equals("Group")) {
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.GROUP_EDIT), true, "EditGroup", "Edit"));
            }
        }
        if (node instanceof Role) {
            if (tab.equals("Role")) {
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.ROLE_EDIT), true, "EditRole", "Edit"));
            }
        }
        if (node instanceof Sprint) {
            if (tab.equals("Sprint")) {
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.SPRINT_EDIT), true, "EditSprint", "Edit"));
            }
        }
        if (node instanceof State) {
            if (tab.equals("State")) {
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.STATE_EDIT), true, "EditState", "Edit"));
            }
        }
        if (node instanceof Status) {
            if (tab.equals("Status")) {
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.STATUS_EDIT), true, "EditStatus", "Edit"));
            }
        }
        if (node instanceof Task) {
            if (node instanceof Anchor) {
                if (tab.equals("Anchor")) {
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.ANCHOR_EDIT), true, "EditAnchor", "Edit"));
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.NODE_POST_COMMENT), true, "Comment", "Post Comment"));
                    buttonList.add(new ButtonValue(true, true, "ToggleUserInterest", "Toggle Interest"));
                }
            }
            if (node instanceof Activity) {
                if (node instanceof Action) {
                    if (tab.equals("Action")) {
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.ACTION_EDIT), true, "EditAction", "Edit"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.NODE_POST_COMMENT), true, "Comment", "Post Comment"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_CHANGE_STATE), true, "ChangeState", "Change State"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_REASSIGN_RESPONSIBILITY), true, "ReassignResponsibility", "Reassign"));
                        buttonList.add(new ButtonValue(true, true, "ToggleUserInterest", "Toggle Interest"));
                    }
                    if (tab.equals("Time") || tab.equals("Action")) {
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TIME_CREATE), true, "CreateTime", "Create Time"));
                    }
                }
                if (node instanceof Issue) {
                    if (tab.equals("Issue")) {
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.ISSUE_EDIT), true, "EditIssue", "Edit"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.NODE_POST_COMMENT), true, "Comment", "Post Comment"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_CHANGE_STATE), true, "ChangeState", "Change State"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_REASSIGN_RESPONSIBILITY), true, "ReassignResponsibility", "Reassign"));
                        buttonList.add(new ButtonValue(true, true, "ToggleUserInterest", "Toggle Interest"));
                    }
                    if (tab.equals("Time") || tab.equals("Issue")) {
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TIME_CREATE), true, "CreateTime", "Create Time"));
                    }
                }
                if (node instanceof Project) {
                    if (tab.equals("Project")) {
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.PROJECT_EDIT), true, "EditProject", "Edit"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.NODE_POST_COMMENT), true, "Comment", "Post Comment"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_CHANGE_STATE), true, "ChangeState", "Change State"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_REASSIGN_RESPONSIBILITY), true, "ReassignResponsibility", "Reassign"));
                        buttonList.add(new ButtonValue(true, true, "ToggleUserInterest", "Toggle Interest"));
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.PROJECT_EDIT), true, "UpdateTime", "Update Time"));
                    }
                    if (tab.equals("Time") || tab.equals("Project")) {
                        buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TIME_CREATE), true, "CreateTime", "Create Time"));
                    }
                }
            }
        }
        if (node instanceof TaskStateMachine) {
            if (tab.equals("TaskStateMachine")) {
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_TYPE_EDIT), true, "EditTaskStateMachine", "Edit"));
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.TASK_TYPE_EDIT), true, "StateMachine", "State Machine"));
            }
        }
        if (node instanceof User) {
            if (tab.equals("User")) {
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.USER_EDIT), true, "EditUser", "Edit"));
                buttonList.add(new ButtonValue(true, true, "Password", "Password"));
                buttonList.add(new ButtonValue(permissionPKs.contains(Permission.USER_ENABLE), true, "ToggleUserEnabled", "Toggle Enabled"));
            }
        }
        if (node instanceof Node) {
            if (node instanceof SystemNode) {
            }
            if (node instanceof ContactDetailTypes) {
                if (tab.equals("ContactDetailTypes")) {
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.CONTACT_DETAIL_TYPE_EDIT), true, "EditContactDetailType", "Edit"));
                }
            }
            if (node instanceof SystemProperties) {
                if (tab.equals("SystemProperties")) {
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.SYSTEM_PROPERTY_EDIT), true, "EditSystemProperty", "Edit"));
                }
            }
            if (node instanceof LicenceManagement) {
                if (tab.equals("LicenceManagement")) {
                    buttonList.add(new ButtonValue(true, true, "AddLicence", "Add Licence"));
                }
            }
            if (node instanceof Node) {
                if (tab.equals("Node")) {
                    buttonList.add(new ButtonValue(permissionPKs.contains(Permission.NODE_EDIT), true, "EditNode", "Edit"));
                }
            }
        }
        return buttonList;
    }
    
    static public Collection<IdName> getAllRolePairs(KeyLocal key) {
        Collection<IdName> rolePairs = new ArrayList<IdName>();
        for (Role role: lookupRoleBean().findAllRoles(key)) {
            rolePairs.add(new IdName(role.getId(), role.toString()));
        }
        return rolePairs;
    }
    
    static public Collection<IdName> getAllTaskTypePairs(KeyLocal key) {
        Collection<IdName> taskTypePairs = new ArrayList<IdName>();
        for (TaskStateMachine taskStateMachine: lookupTaskStateMachineBean().findAllTaskStateMachines(key)) {
            taskTypePairs.add(new IdName(taskStateMachine.getId(), taskStateMachine.toString()));
        }
        return taskTypePairs;
    }
    
    static public Collection<IdName> getAllUserPairs(KeyLocal key) {
        Collection<IdName> userPairs = new ArrayList<IdName>();
        for (User user: lookupUserBean().findAllUsers(key)) {
            userPairs.add(new IdName(user.getId(), user.toString()));
        }
        return userPairs;
    }
    
    static public Collection<IdName> getAllPersonPairs(KeyLocal key) {
        Collection<IdName> personPairs = new ArrayList<IdName>();
        for (Person person: lookupPersonBean().findAllPersons(key)) {
            personPairs.add(new IdName(person.getId(), person.toString()));
        }
        return personPairs;
    }
    
    static public Collection<IdName> getAllGroupPairs(KeyLocal key) {
        Collection<IdName> groupPairs = new ArrayList<IdName>();
        for (Group group: lookupGroupBean().findAllGroups(key)) {
            groupPairs.add(new IdName(group.getId(), group.toString()));
        }
        return groupPairs;
    }
    
/*    static public Collection<IdName> getAllDepartmentPairs(KeyLocal key) {
        Collection<IdName> departmentPairs = new ArrayList<IdName>();
        for (Department department: lookupDepartmentBean().findAllDepartments(key)) {
            departmentPairs.add(new IdName(department.getId(), department.getQualifiedName()));
        }
        return departmentPairs;
    }*/
    
    static public Collection getAllNotificationPairs(KeyLocal key) {
        Collection<IdName> notificationPairs = new ArrayList<IdName>();
        for (NotificationMechanism nm: NotificationMechanism.values()) {
            notificationPairs.add(new IdName((long) nm.ordinal(), nm.toString()));
        }
        return notificationPairs;
    }
    
    static public Collection<IdName> getAllStatePairs(KeyLocal key) {
        Collection<IdName> statePairs = new ArrayList<IdName>();
        for (State state: lookupStateBean().findAllStates(key)) {
            statePairs.add(new IdName(state.getId(), state.getName()));
        }
        return statePairs;
    }
    
    static public Collection<IdName> getAllButStartStatePairs(KeyLocal key) {
        Collection<IdName> statePairs = new ArrayList<IdName>();
        State startState = lookupStateBean().findStartState(key);
        for (State state: lookupStateBean().findAllStates(key)) {
            if (!state.equals(startState))
                statePairs.add(new IdName(state.getId(), state.getName()));
        }
        return statePairs;
    }
    
    static public Collection<IdName> getAllStatusPairs(KeyLocal key) {
        Collection<IdName> statusPairs = new ArrayList<IdName>();
        for (Status status: lookupStatusBean().findAllStatuses(key)) {
            statusPairs.add(new IdName(status.getId(), status.getName()));
        }
        return statusPairs;
    }
    
    static public Collection<IdName> getAllContactablePairs(KeyLocal key) {
        TreeModel contactableTreeModel = lookupContactableBean().getContactableTree(key);
        Collection<IdName> contactablePairs = new ArrayList<IdName>();
        recursiveAddContactable(contactableTreeModel, contactableTreeModel.getRoot(), contactablePairs, 0);
        return contactablePairs;
    }

    public static void recursiveAddContactable(TreeModel contactableTreeModel, Object node, Collection<IdName> contactablePairs, int level) {
        Object userObject = ((DefaultMutableTreeNode)node).getUserObject();
        if (userObject instanceof Contactable) {
            StringBuffer buffer = new StringBuffer();
            for (int i = 0; i < level-1; i++)
                buffer.append(" - ");
            Contactable contactable = (Contactable)userObject;
            buffer.append(contactable.toString());
            contactablePairs.add(new IdName(contactable.getId(), buffer.toString()));
        }
        for (int i = 0; i < contactableTreeModel.getChildCount(node); i++) {
            Object nextNode = contactableTreeModel.getChild(node, i);
            recursiveAddContactable(contactableTreeModel, nextNode, contactablePairs, level+1);
        }
    }

    static private TreeLocal lookupTreeBean() {
        try {
            Context c = new InitialContext();
            return (TreeLocal) c.lookup("java:comp/env/TreeBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private PersonLocal lookupPersonBean() {
        try {
            Context c = new InitialContext();
            return (PersonLocal) c.lookup("java:comp/env/PersonBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private ContactableLocal lookupContactableBean() {
        try {
            Context c = new InitialContext();
            return (ContactableLocal) c.lookup("java:comp/env/ContactableBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private UserLocal lookupUserBean() {
        try {
            Context c = new InitialContext();
            return (UserLocal) c.lookup("java:comp/env/UserBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private RoleLocal lookupRoleBean() {
        try {
            Context c = new InitialContext();
            return (RoleLocal) c.lookup("java:comp/env/RoleBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private GroupLocal lookupGroupBean() {
        try {
            Context c = new InitialContext();
            return (GroupLocal) c.lookup("java:comp/env/GroupBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private StatusLocal lookupStatusBean() {
        try {
            Context c = new InitialContext();
            return (StatusLocal) c.lookup("java:comp/env/StatusBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private StateLocal lookupStateBean() {
        try {
            Context c = new InitialContext();
            return (StateLocal) c.lookup("java:comp/env/StateBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private TaskStateMachineLocal lookupTaskStateMachineBean() {
        try {
            Context c = new InitialContext();
            return (TaskStateMachineLocal) c.lookup("java:comp/env/TaskStateMachineBean");
        } catch (NamingException ne) {
            Logger.getLogger(NodeUtil.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

}
